package tool

import cats.data.Validated
import implicits.Implicits._
import play.api.i18n.Messages

/**
 * Created by yz on 12/3/2020
 */

class VarInfoFileValidTool(lines: List[List[String]])(implicit messages: Messages) {

  val headers = lines.head
  val fileInfo = messages("varInfoFile")

  def validHeadersRepeat = {
    val repeatHeaders = headers.diff(headers.distinct)
    val valid = repeatHeaders.isEmpty
    Validated.cond(valid, true, s"${messages("headerRepeat", fileInfo, repeatHeaders.head)}")
  }

  def validColumnNum = {
    val notAnnoLines = lines.notAnnoLines
    val headers = notAnnoLines.head
    val info = notAnnoLines.drop(1).zipWithIndex.map { case (tmpColumns, i) =>
      val columns = tmpColumns
      val valid = columns.size <= headers.size
      val inMessage = if (!valid) {
        s"${messages("columnNumValid", fileInfo, i + 2)}"
      } else ""
      (valid, inMessage)
    }
    val valid = info.forall(_._1)
    val outMessages = info.map(_._2).notEmptyLines
    Validated.cond(valid, true, outMessages.head)
  }

  def validColumnsRepeat = {
    val repeatColumns = List[String]()
    val info = repeatColumns.map { header =>
      val totalColumns = lines.selectOneColumn(header)
      val repeatValues = totalColumns.diff(totalColumns.distinct)
      val inValid = repeatValues.isEmpty
      val inMessage = if (!inValid) {
        val repeatValue = repeatValues.head
        val j = header
        val i = totalColumns.lastIndexOf(repeatValue)
        s"${messages("columnRepeat", fileInfo, i + 1, j + 1)}"
      } else ""
      (inValid, inMessage)
    }
    val valid = info.forall(_._1)
    val outMessages = info.map(_._2)
    Validated.cond(valid, true, outMessages.head)
  }

  def validHeadersExist = {
    val hasHeaders = List[String]()
    val noExistHeaders = hasHeaders.diff(headers.toLowerCase)
    val valid = noExistHeaders.isEmpty
    Validated.cond(valid, true, s"${messages("headerNoExist", fileInfo, noExistHeaders.head)}")
  }

}

object VarInfoFileValidTool {

  def valid(lines: List[List[String]])(implicit messages: Messages) = {
    val fileValidTool = new VarInfoFileValidTool(lines)
    import fileValidTool._
    validHeadersRepeat.andThen { b =>
      validColumnNum
    }.andThen { b =>
      validHeadersExist
    }.andThen { b =>
      validColumnsRepeat
    }.leftMap { x =>
      s"${messages("incorrectFormat")}!\n${x}"
    }

  }

}
